package com.zeus.core.log.appender;

import com.zeus.common.log.ZeusLoggerConfig;
import com.zeus.common.utils.StackTraceUtils;
import com.zeus.core.context.ZeusContext;
import com.zeus.core.report.ZeusReportClient;
import com.zeus.core.report.ZeusReportLog4jClient;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Log4j日志监控Appender
 *
 * @author wangfeixiong126@gmail.com  2021/4/28 10:40
 */
public class Log4jMonitorAppender extends AppenderSkeleton {
    private final static Logger logger = LoggerFactory.getLogger(Log4jMonitorAppender.class);

    /**
     * 构造
     *
     * @author wangfeixiong126@gmail.com  2021/4/28 10:43
     */
    public Log4jMonitorAppender() {
        // default
    }

    /**
     * 自定义append
     *
     * @param loggingEvent loggingEvent
     * @author wangfeixiong126@gmail.com  2021/4/28 10:56
     */
    @Override
    protected void append(LoggingEvent loggingEvent) {
        try {
            if (loggingEvent != null && loggingEvent.getLevel().isGreaterOrEqual(Level.ERROR)) {
                // 开关
                if (!ZeusContext.getContext().alarmEnable()) {
                    return;
                }
                // 内容是否可以忽略
                if (ZeusContext.getContext().checkAlarmContentIgnore(loggingEvent.getLoggerName(),
                    loggingEvent.getMessage().toString(), getStackTrace(loggingEvent.getThrowableInformation()))) {
                    return;
                }

                // 发送报告
                ZeusReportClient client = new ZeusReportLog4jClient(loggingEvent);
                client.complete();
            }
        } catch (Throwable e) {
            if (logger.isWarnEnabled() && ZeusLoggerConfig.needEnableLogger()) {
                logger.warn("### Zeus日志监控模块, Log4j日志监控服务执行失败，错误信息 >> errMsg = {}", e.getMessage());
            }
        }
    }

    /**
     * close
     *
     * @author wangfeixiong126@gmail.com  2021/4/28 11:12
     */
    @Override
    public void close() {

    }

    /**
     * 获取Layout
     *
     * @return Layout
     * @author wangfeixiong126@gmail.com  2021/4/28 10:46
     */
    @Override
    public Layout getLayout() {
        return super.getLayout();
    }

    /**
     * 是否需要 layout
     *
     * @return false
     * @author wangfeixiong126@gmail.com  2021/4/28 10:45
     */
    @Override
    public boolean requiresLayout() {
        return false;
    }

    /**
     * 获取堆栈信息
     *
     * @param throwableInformation throwableInformation
     * @return 堆栈信息
     * @author f1ybear_wang  2022/2/8 6:36 下午
     */
    private String getStackTrace(ThrowableInformation throwableInformation) {
        try {
            if (throwableInformation == null) {
                return null;
            }
            return StackTraceUtils.getStackTrace(throwableInformation.getThrowable());
        } catch (Throwable e) {
            if (logger.isWarnEnabled() && ZeusLoggerConfig.needEnableLogger()) {
                logger.warn("### Zeus日志监控模块, Log4j日志监控服务加工堆栈信息出现异常:", e);
            }
        }
        return null;
    }
}
